/***************************************************************
 *
 * Filename：TCPServe.h
 * Abstract：the design of TCP
 * version ：1.0
 *
 * Copyright (c) 2011 SCUT DT&P FY&XC
 *
***************************************************************/

#include "TCPServe.h"

//
TCPServer::TCPServer(QString filename,FileSendWindow* Filesw)
{
    tcpServer = new QTcpServer(this);
    fileName = filename;
    FileS = Filesw;
    //tcpServer->bind(IPMSG_DEFAULT_PORT);
    initTCPServer();
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));
    connect(FileS,SIGNAL(stopsendfile()),this,SLOT(stopsendfile()));

}

//
void TCPServer::initTCPServer()
{
    loadSize = 4*1024;
    qDebug()<<"TCP in TCPServer::initTCPServer";
    TotalBytes = 0;
    bytesWritten = 0;
    bytesToWrite = 0;
    //bytesReceived = 0;
    //fileNameSize = 0;
    start();
    //tcpServer->close();
}

//
void TCPServer::start()
{
    qDebug()<<"Start to listen in TCPServer::start";
    qDebug()<<QHostAddress::LocalHost;
    if(!tcpServer->listen(QHostAddress::Any,IPMSG_DEFAULT_PORT)) {
        //监听本地主机的端口，如果出错就输出错误信息，并关闭
        qDebug()<<tcpServer->errorString()<<"in TCPServer::start";
        //close();
    }
}

//接收连接函数
void TCPServer::acceptConnection()
{
    FileS->setlabeltext("begin to connect to client!!!");
    FileS->setopenstate(false);
    FileS->setsendstate(true);
    clientConnection = tcpServer->nextPendingConnection();
    connect(clientConnection,SIGNAL(bytesWritten(qint64)),SLOT(updateClientProgress(qint64)));
    localFile = new QFile(fileName);
    if(!localFile->open((QFile::ReadOnly))){
        //以只读方式打开
        //QMessageBox::warning(this,tr("应用程序"),tr("无法读取文件 %1:\n%2").arg(fileName).arg(localFile->errorString()));
        return;
    }
    TotalBytes = localFile->size();
    QDataStream sendOut(&outBlock,QIODevice::WriteOnly);
    sendOut.setVersion(QDataStream::Qt_4_6);
    time.start();  //开始计时
    QString currentFile = fileName.right(fileName.size() - fileName.lastIndexOf('/')-1);
    //依次写入总大小信息空间，文件名大小信息空间，文件名,前两项暂设为零
    sendOut<<qint64(0)<<qint64(0)<<currentFile;
    qDebug()<<"sendOut:"<<sendOut;
    //这里的总大小是文件名大小等信息和实际文件大小的总和
    TotalBytes += outBlock.size();
    qDebug()<<"TotalBytes:"<<TotalBytes;
    //返回outBolock的开始，用实际的大小信息代替两个qint64(0)空间
    sendOut.device()->seek(0);
    sendOut<<TotalBytes<<qint64((outBlock.size()-sizeof(qint64)*2));
    qDebug()<<"sendOut:"<<sendOut;
    //发送完头数据后剩余数据的大小
    bytesToWrite = TotalBytes - clientConnection->write(outBlock);
    qDebug()<<currentFile<<TotalBytes<<bytesToWrite;
    outBlock.resize(0);
}

//更新进度条
void TCPServer::updateClientProgress(qint64 numBytes)
{
    bytesWritten += (int)numBytes;
    if(bytesToWrite > 0){
        outBlock = localFile->read(qMin(bytesToWrite,loadSize));
        bytesToWrite -= (int)clientConnection->write(outBlock);
        outBlock.resize(0);
    }
    else{
        localFile->close();
    }
    FileS->setlabeltext(QString("begin to send \"%1\" !!!").arg(currentFile));
    FileS->setProgressBar(TotalBytes,bytesWritten);
    float useTime = time.elapsed();
    double speed = bytesWritten / useTime;
    QString TT = QString("to send %1MB (%2MB/s) \ntotal %3MB used time:%4s\nleft time:%5s")
                                  .arg(bytesWritten / (1024*1024))//已发送
                                  .arg(speed*1000/(1024*1024),0,'f',2)//速度
                                 .arg(TotalBytes / (1024 * 1024))//总大小
                                 .arg(useTime/1000,0,'f',0)//用时
                                .arg(TotalBytes/speed/1000 - useTime/1000,0,'f',0);//剩余时间
    FileS->setProgresstext(TT);
   //num.sprintf("%.1f KB/s", (bytesWritten*1000) / (1024.0*time.elapsed()));
    if(bytesWritten == TotalBytes) {
        FileS->setlabeltext(QString("Finish to send \"%1\" !!!!!!!!!!!!!!!").arg(currentFile));
        FileS->setsendstate(false);
        //emit finishSendFile(currentFile);
    }

}

//
void TCPServer::displayError(QAbstractSocket::SocketError) //错误处理
{
    qDebug() <<clientConnection->errorString();
    clientConnection->close();
}

//被对方拒绝
void TCPServer::refused()
{
    tcpServer->close();
    //ui->serverStatusLabel->setText(tr("对方拒绝接收！！！"));
}

void TCPServer::stopsendfile()
{
    tcpServer->close();
}
